home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / comm2 / amislt14.lha / AmiSlate / SlateRexx / checkers.rexx < prev    next >
OS/2 REXX Batch file  |  1996-01-27  |  18KB  |  655 lines

  1. /* Checkers for AmiSlate v1.1! */
  2. /* This program should be run on a screen with at least 4 colors */
  3.  
  4. /* Get our host's name--always given as first argument when run from Amislate */
  5. parse arg CommandPort ActiveString
  6.  
  7. if (length(CommandPort) == 0) then do
  8.     say ""
  9.     say "Usage:  rx checkers.rexx <REXXPORTNAME>"
  10.     say "        (REXXPORTNAME is usually AMISLATE)"
  11.     say ""
  12.     say "Or run from the Rexx menu within AmiSlate."
  13.     say ""
  14.     exit 0
  15.     end
  16.     
  17. /* Send all commands to this host */
  18. address (CommandPort) 
  19. options results
  20.  
  21. lock ON
  22.  
  23. /* See if we're connected */
  24. GetRemoteStateAttrs stem rstateattrs.
  25. if (rstateattrs.mode > -1) then do
  26.         /* Parse command line argument to see if we've been activated by 
  27.            a remote request or a local user */
  28.         check = upper(left(ActiveString,3))
  29.         if (upper(left(ActiveString,3)) ~= 'RE') then 
  30.             GlobData.localplayer = 1
  31.         else
  32.             GlobData.localplayer = -1
  33.         end
  34.     else do
  35.         GlobData.localplayer = 0    /* i.e. we're both players */
  36.         end
  37.         
  38. if (GlobData.localplayer > 0) then do
  39.     call SetStatus("Requesting game from remote user... please wait.")
  40.     RemoteRexxCommand '"'||"Would you like to play Checkers?"||'"' "slaterexx:Checkers.rexx"
  41.     
  42.         waitevent stem handshake. MESSAGE
  43.         if (handshake.message == 0) then 
  44.         do
  45.             call SetStatus("Checkers Game Refused")
  46.             lock off
  47.             exit 0
  48.         end
  49.     end
  50.  
  51. call SetStatus("Beginning Checkers...")
  52.  
  53. call ResetGameState
  54. call SetGlobalData
  55. if (GlobData.localplayer >= 0) then call DrawBoard
  56.  
  57. call NextTurn
  58. call HandleEvents
  59.  
  60. lock OFF
  61. exit 0
  62.  
  63. /* Global Data structure:
  64.  
  65.     GlobData.Xspace.[step] (int)     : horizontal pixel offsets to the center of each coord (0-16)
  66.     GlobData.XSize    (int)         : total width of each element
  67.     GlobData.Yspace.[step] (int)     : vertical pixel offsets to the center of each coord (0-16)
  68.     GlobData.YSize    (int)         : total height of each element
  69.  
  70.     (board state)
  71.     GlobData.board.[0..8].[0..8]     : two-dimensional board array
  72.     
  73.     (game state)
  74.     GlobData.turn             : whose turn it is
  75.     GlobData.localplayer              : which player is on local machine; 0 if both are
  76.  
  77.      (color info)
  78.     GlobData.PieceColor.[playernum]  : color of pieces for this player
  79.  
  80. */
  81.  
  82. /* --------------------------------------------------------------- */
  83. /* procedure HandleEvents                        */
  84. /* --------------------------------------------------------------- */
  85. HandleEvents: procedure expose GlobData. AMessage.
  86.  
  87. AMessage.TIMEOUT     = 1    /* No events occurred in specified time period */
  88. AMessage.MESSAGE     = 2    /* Message recieved from remote Amiga */
  89. AMessage.MOUSEDOWN   = 4    /* Left mouse button press in drawing area */
  90. AMessage.MOUSEUP     = 8    /* Left mouse button release in drawing area */
  91. AMessage.RESIZE      = 16    /* Window was resized--time to redraw screen? */ 
  92. AMessage.QUIT        = 32    /* AmiSlate is shutting down */
  93. AMessage.CONNECT     = 64    /* Connection established */
  94. AMessage.DISCONNECT  = 128    /* Connection broken */
  95. AMessage.TOOLSELECT  = 256    /* Tool Selected */
  96. AMessage.COLORSELECT = 512    /* Palette Color selected */
  97. AMessage.KEYPRESS    = 1024    /* Key pressed */
  98. AMessage.MOUSEMOVE   = 2048     /* Mouse was moved */
  99.  
  100. fromx = -1
  101. fromy = -1
  102. jumponlymode = 0
  103.  
  104. do while(1)
  105.     waitevent stem event. RESIZE MOUSEDOWN MOUSEUP TOOLSELECT MESSAGE DISCONNECT
  106.  
  107.     if (event.type == AMessage.QUIT) then exit 0
  108.     
  109.     if (event.type == AMessage.DISCONNECT) then do
  110.         call SetStatus("Connection broken--both players now local.")
  111.         GlobData.localplayer = 0
  112.         end
  113.    
  114.     if (event.type == AMessage.MESSAGE) then do
  115.         parse var event.message fx fy tx ty
  116.         if (fx = -1) then 
  117.             call NextTurn
  118.         else 
  119.             call PlaceMove((fx+0), (fy+0), (tx+0), (ty+0), 0)  /* update our internals--the (+0) forces the vars back into numeric format */
  120.         end
  121.  
  122.     if (event.type == AMessage.RESIZE) then do
  123.         if ((GlobData.localplayer == GlobData.turn)|(GlobData.localplayer == 0)) then do
  124.             cturn = GlobData.turn
  125.             call SetGlobalData
  126.             call DrawBoard
  127.                 if (fromx ~= -1) then call HilitePiece(fromx, fromy)
  128.             call ColorBorder(GlobData.PieceColor.cturn)
  129.             call SetStatus("_LAST")
  130.         end
  131.         else do
  132.             /* else just update our internal vars */
  133.             call SetGlobalData
  134.             call SetStatus("_LAST")
  135.         end
  136.     end
  137.     
  138.     if ((event.type == AMessage.MOUSEDOWN)&((GlobData.turn = GlobData.localplayer)|(GlobData.localplayer == 0))) then do
  139.         whatclickedx = ChopRange(trunc((event.x-GlobData.BORDER_H)/(GlobData.XSize)),0,7)
  140.         whatclickedy = ChopRange(trunc((event.y-GlobData.BORDER_V)/(GlobData.YSize)),0,7)
  141.         if (fromx >= 0) then do
  142.             if ((whatclickedx == fromx)&(whatclickedy == fromy)) then do
  143.                 /* cancel that move! */
  144.                 call HilitePiece(fromx, fromy)
  145.                 fromx = -1
  146.                 fromy = -1
  147.                 if (jumponlymode > 0) then do
  148.                     /* that's all for the move then */
  149.                     jumponlymode = 0
  150.                     call NextTurn
  151.                     if (localplayer ~= 0) then call TransmitMove(-1, -1, -1, -1)
  152.                     end
  153.                 end
  154.             else do
  155.                 if ((MoveOkay(fromx, fromy, whatclickedx, whatclickedy) == 1)&((jumponlymode == 0)|(abs(whatclickedx-fromx)==2))) then do
  156.                     if (localplayer ~= 0) then call TransmitMove(fromx, fromy, whatclickedx, whatclickedy)
  157.                     if (PlaceMove(fromx, fromy, whatclickedx, whatclickedy, 1) == 2) then do
  158.                         call HilitePiece(whatclickedx, whatclickedy)
  159.                         jumponlymode = jumponlymode + 1
  160.                         call TellExtraJump(jumponlymode)
  161.                         fromx = whatclickedx
  162.                         fromy = whatclickedy
  163.                         end
  164.                     else do
  165.                         if (localplayer ~= 0) then call TransmitMove(-1, -1, -1, -1)
  166.                         jumponlymode = 0
  167.                         call NextTurn
  168.                         fromx = -1
  169.                         fromy = -1
  170.                         end
  171.                     end 
  172.                     else DisplayBeep LOCAL
  173.                 end 
  174.             end
  175.         else do
  176.             if ((GlobData.board.whatclickedx.whatclickedy * GlobData.turn) > 0) then do
  177.                 fromx = whatclickedx
  178.                 fromy = whatclickedy
  179.                 call HilitePiece(fromx, fromy)
  180.                 end
  181.             end
  182.     end
  183.     end
  184.     return 1
  185.  
  186.  
  187. /* --------------------------------------------------------------- */
  188. /* procedure NextTurn                           */
  189. /*                                    */
  190. /* --------------------------------------------------------------- */
  191. NextTurn: procedure expose GlobData.
  192.     /* Swap turns */
  193.     GlobData.turn = -GlobData.turn
  194.  
  195.     negone = -1
  196.     player.1 = "Player 1"
  197.     player.negone = "Player 2"
  198.     cturn = GlobData.turn
  199.         
  200.     call SetStatus("Just a sec...")
  201.     if (GlobData.turn == GlobData.localplayer) then call ColorBorder(0)
  202.     
  203.     /* Check to see if the new player has a move available */
  204.     if (CanMove() == 0) then do
  205.         call SetStatus("Sorry, " || player.cturn || ", but you must forfeit your turn.")
  206.         call Delay(100)
  207.         if (localplayer ~= 0) then TransmitMove(-1,-1,-1,-1)
  208.         call NextTurn    /* recursive! :) */
  209.         return 1
  210.         end
  211.  
  212.     /* local game code */
  213.     if (Globdata.localplayer == 0) then do
  214.         call SetStatus(player.cturn || ", it's your turn to move a checker.")
  215.         call ColorBorder(GlobData.PieceColor.cturn)
  216.         return 1
  217.         end
  218.     
  219.     /* two machine game code */
  220.     if (GlobData.turn == GlobData.localplayer) then do
  221.         call SetStatus(player.cturn || ", it's your turn to move a checker.")
  222.         call ColorBorder(GlobData.PieceColor.cturn)
  223.         end    
  224.     else call SetStatus("Wait for other player to move.")    
  225.     return 1
  226.  
  227.  
  228. /* --------------------------------------------------------------- */
  229. /* procedure ColorBorder                       */
  230. /*                                    */
  231. /* Colors the border the color indicated in the param            */
  232. /*                                   */
  233. /* --------------------------------------------------------------- */
  234. ColorBorder: procedure expose GlobData.
  235.     parse arg color
  236.     
  237.     SetFPen color
  238.     
  239.     /* Fill each side of the border with a square */
  240.     /* rely on AmiSlate's clipping to deal with extra material */
  241.     square 0 0 10000 (GlobData.YSpace.0)-1 FILL
  242.     square 0 0 (GlobData.XSpace.0)-1 10000 FILL
  243.     square (GlobData.XSpace.8)+1 0 10000 10000 FILL
  244.     square 0 (GlobData.YSpace.8)+1 10000 10000 FILL
  245.     return 1
  246.     
  247.  
  248. /* --------------------------------------------------------------- */
  249. /* procedure CanMove                           */
  250. /*                                    */
  251. /* Returns 1 if there is a move available for the current player   */
  252. /* else 0                               */
  253. /*                                    */
  254. /* --------------------------------------------------------------- */
  255. CanMove: procedure expose GlobData.
  256.     
  257.     num1 = 0
  258.     num2 = 0
  259.     negone = -1
  260.     
  261.     return 1
  262.  
  263.  
  264. /* --------------------------------------------------------------- */
  265. /* procedure PieceCanJump                       */
  266. /*                                    */
  267. /* Returns 1 if there is a jump available for the piece at the     */
  268. /* give spot, else returns 0                        */
  269. /*                                    */
  270. /* --------------------------------------------------------------- */
  271. PieceCanJump: procedure expose GlobData.
  272.     parse arg fx, fy
  273.     
  274.     if (MoveOkay(fx,fy,fx+2,fy+2) == 1) then return 1
  275.     if (MoveOkay(fx,fy,fx-2,fy+2) == 1) then return 1
  276.     if (MoveOkay(fx,fy,fx+2,fy-2) == 1) then return 1
  277.     if (MoveOkay(fx,fy,fx-2,fy-2) == 1) then return 1
  278.     return 0
  279.     
  280.  
  281.  
  282. /* --------------------------------------------------------------- */
  283. /* procedure GameWon                           */
  284. /*                                    */
  285. /* displays a message saying who won, based on the arg, and exits. */
  286. /*                                   */
  287. /* --------------------------------------------------------------- */
  288. GameWon: procedure
  289.     parse arg winner
  290.     
  291.     if (winner == "Tie") then winstring = "The game ends in a tie."
  292.     else winstring = winner || " has won the game!"
  293.     
  294.     EasyRequest "Winner!" '"'||winstring||'"' "Okay"
  295.     call SetStatus("Game over.  Rerun script to play again.")
  296.     lock off
  297.     exit 0
  298.     
  299.  
  300. /* --------------------------------------------------------------- */
  301. /* procedure PlaceMove                           */
  302. /*                                    */
  303. /* does a move by placing a piece at (x,y) and turning over all    */
  304. /* appropriate pieces                           */
  305. /*                                   */
  306. /* returns 2 if the piece should be given the option of another    */
  307. /* jump after this one.                        */
  308. /*                                   */
  309. /* --------------------------------------------------------------- */
  310. PlaceMove: procedure expose GlobData.
  311.     parse arg fx, fy, tx, ty, draw
  312.     
  313.     negone = -1
  314.     piece = GlobData.board.fx.fy
  315.     GlobData.board.fx.fy = 0
  316.  
  317.     /* If it wasn't a king, check to see if it needs to be kinged */
  318.     if (((piece == 1)&(ty == 7))|((piece == -1)&(ty == 0))) then piece = piece * 2
  319.  
  320.     GlobData.board.tx.ty = piece
  321.  
  322.     if (draw == 1) then do
  323.         call DrawPiece(fx, fy)
  324.         call DrawPiece(tx, ty)
  325.         end
  326.     
  327.     /* check to see if it was a jump */
  328.     if (abs(tx-fx) > 1) then do
  329.         mx = (tx+fx)%2
  330.         my = (ty+fy)%2
  331.         GlobData.board.mx.my = 0
  332.         if (draw == 1) then call DrawPiece(mx, my)
  333.  
  334.         /* decrement appropriate piece-counter */
  335.         opponent = -GlobData.turn
  336.         GlobData.pieces.opponent = GlobData.pieces.opponent - 1
  337.  
  338.         /* check for a win */
  339.         if (GlobData.pieces.1 == 0) then do
  340.             call ColorBorder(GlobData.PieceColor.1)
  341.             call GameWon("Player 1")
  342.             end
  343.         else if (GlobData.pieces.negone == 0) then do
  344.             call ColorBorder(GlobData.PieceColor.negone)
  345.             call GameWon("Player 2")
  346.             end
  347.             
  348.         /* Can we jump again? */
  349.         if (PieceCanJump(tx,ty) == 1) then return 2
  350.         end
  351.     
  352.     return 1
  353.  
  354.  
  355. /* --------------------------------------------------------------- */
  356. /* procedure MoveOkay                           */
  357. /*                                    */
  358. /* returns 1 if move is acceptable, or -1 if it is illegal.       */
  359. /*                                    */
  360. /* --------------------------------------------------------------- */
  361. MoveOkay: procedure expose GlobData.
  362.     parse arg fx, fy, tx, ty
  363.  
  364.     negone = -1
  365.     
  366.     /* First rule: all moves on the board */
  367.     if ((fx < 0)|(fy < 0)|(fx > 7)|(fy > 7)|(tx < 0)|(ty < 0)|(tx > 7)|(ty > 7)) then return 0
  368.     
  369.     /* Must be moving our own piece */
  370.     if ((GlobData.board.fx.fy * GlobData.turn) <= 0) then return 0
  371.  
  372.     /* Place we move to must be empty */
  373.     if (GlobData.board.tx.ty ~= 0) then return 0
  374.     
  375.     /* If it is a regular piece, is it in the right direction? */
  376.     if (abs(GlobData.board.fx.fy) == 1) then do
  377.         if ((GlobData.turn == 1)&(fy > ty)) then return 0
  378.         if ((GlobData.turn == -1)&(fy < ty)) then return 0
  379.         end
  380.     
  381.     /* No moving too far! */
  382.     if (abs(tx-fx) > 2) then return 0
  383.     if (abs(ty-fy) > 2) then return 0
  384.     
  385.     /* must be diagonal */
  386.     if (abs(tx-fx) ~= abs(ty-fy)) then return 0
  387.     
  388.     /* If it is a jump, make sure there is someone there to jump */    
  389.     if (abs(tx-fx) > 1) then do
  390.         mx = (fx+tx)%2
  391.         my = (fy+ty)%2
  392.         if (GlobData.board.mx.my * GlobData.turn >= 0) then return 0
  393.         end
  394.                 
  395.     /* No move available */    
  396.     return 1
  397.     
  398.     
  399.  
  400. /* --------------------------------------------------------------- */
  401. /* procedure ResetGameState                       */
  402. /* --------------------------------------------------------------- */
  403. ResetGameState: procedure expose GlobData.
  404.     negone = -1;
  405.     
  406.     GlobData.turn = -1;
  407.     
  408.     /* first clear the board */
  409.     do i = 0 to 7
  410.         do j = 0 to 7
  411.             GlobData.board.i.j = 0
  412.         end
  413.     end
  414.  
  415.     /* then add in initial pieces --play on color 3 */
  416.     do i = 0 to 2
  417.         do j = 0 to 3
  418.             x = j*2
  419.             if (i==1) then x = x + 1
  420.             GlobData.board.x.i = 1
  421.             xx = 7 - x
  422.             yy = i + 5
  423.             GlobData.board.xx.yy = -1
  424.             end
  425.         end    
  426.     
  427.     GlobData.pieces.1 = 12
  428.     GlobData.pieces.negone = 12
  429.     
  430.     return 1
  431.  
  432. /* --------------------------------------------------------------- */
  433. /* procedure SetGlobalData                       */
  434. /* --------------------------------------------------------------- */
  435. SetGlobalData: procedure expose GlobData.
  436.     negone = -1
  437.     
  438.     /* constants */
  439.     GlobData.BORDER_H = 5
  440.     GlobData.BORDER_V = 10
  441.     
  442.     /* Check to see whether we are connected */
  443.        GetWindowAttrs stem winattrs.
  444.        BoardWidth = winattrs.width  - 58 - (GlobData.BORDER_H*2)
  445.        BoardHeight= winattrs.height - 55 - (GlobData.BORDER_V*2)
  446.  
  447.     /* Set up offsets */
  448.     DO i=0 to 8
  449.       GlobData.Xspace.i = trunc(BoardWidth  * i / 8) + GlobData.BORDER_H
  450.       GlobData.Yspace.i = trunc(BoardHeight * i / 8) + GlobData.BORDER_V
  451.       end
  452.  
  453.     GlobData.XSize = trunc(BoardWidth / 8)
  454.     GlobData.YSize = trunc(BoardHeight / 8)
  455.  
  456.        if (winattrs.depth < 2) then do
  457.         EasyRequest Checkers_Error '"'||"You need at least a 4-color screen to play Checkers!"||'"' '"'||"Abort Checkers"||'"'
  458.         call SetStatus("Checkers game exited.")
  459.         lock off
  460.         exit 0
  461.         end 
  462.  
  463.     GlobData.PieceColor.1 = 1
  464.     GlobData.PieceColor.negone = 2
  465.     GlobData.OutlineColor.1 = 2
  466.     GlobData.OutlineColor.negone = 1
  467.     return 1
  468.  
  469.  
  470. /* --------------------------------------------------------------- */
  471. /* procedure DrawBoard                                             */
  472. /* --------------------------------------------------------------- */
  473. DrawBoard: procedure expose GlobData.
  474.     SetFColor 0 0 0        /* Get a black pen */
  475.  
  476.     Clear
  477.  
  478.     SetWindowTitle '"' || "Hang on, drawing the board..." || '"'
  479.     call SetColors
  480.     
  481.     do i = 0 to 7
  482.         do j = 0 to 7
  483.             call DrawPiece(i,j)
  484.             end
  485.         end
  486.         
  487.     call SetStatus("_LAST")
  488.     return 1
  489.  
  490.  
  491. /* XORs the given piece */
  492. HiLitePiece: procedure expose GlobData.
  493.     parse arg xc, yc
  494.     
  495.     /* Draw the piece in the square on the LOWER RIGHT of this intersection */
  496.     cx = MidwayBetween(xc,xc+1,X)
  497.     cy = MidwayBetween(yc,yc+1,Y)    
  498.     circle cx cy trunc(GlobData.XSize/3) trunc(GlobData.YSize/3) FILL XOR
  499.     return 1
  500.  
  501.     
  502. /* Draws the piece listed at coords xc, yc */
  503. DrawPiece: procedure expose GlobData.
  504.     parse arg xc, yc
  505.  
  506.     isking = 0
  507.     piece = GlobData.board.xc.yc
  508.     
  509.     if (abs(piece) == 2) then do
  510.         piece = piece % 2
  511.         isking = 1
  512.         end
  513.         
  514.     /* Draw the square in the correct background color */
  515.     if ((xc//2) == (yc//2)) then 
  516.         SetFPen 3
  517.     else
  518.         SetFPen 0
  519.  
  520.     nx = xc + 1
  521.     ny = yc + 1        
  522.  
  523.     square GlobData.XSpace.xc+1 GlobData.YSpace.yc+1 GlobData.XSpace.nx-1 GlobData.YSpace.ny-1 FILL    
  524.  
  525.     SetFPen 1
  526.     square GlobData.XSpace.xc GlobData.YSpace.yc GlobData.XSpace.nx GlobData.YSpace.ny
  527.  
  528.     /* If there's no piece here, we're done */
  529.     if (piece == 0) then return 0
  530.     
  531.     /* Draw the piece in the square on the LOWER RIGHT of this intersection */
  532.     cx = MidwayBetween(xc,nx,X)
  533.     cy = MidwayBetween(yc,ny,Y)    
  534.     
  535.     SetFPen GlobData.PieceColor.piece
  536.     circle cx cy GlobData.XSize%3 GlobData.YSize%3 FILL
  537.     SetFPen GlobData.OutlineColor.piece
  538.     circle cx cy GlobData.XSize%3 GlobData.YSize%3 
  539.     
  540.     /* Draw a crown if it's a king */
  541.     if (isking == 1) then do
  542.         left  = cx - (GlobData.XSize%6)
  543.         right = cx + (GlobData.XSize%6)
  544.         top   = cy - (GlobData.YSize%6)
  545.         bottom= cy + (GlobData.YSize%6)
  546.         width = right - left
  547.         height= bottom - top
  548.         
  549.         /* Draw outline of crown */
  550.         penreset
  551.         pen left top
  552.         pen (left + (width%5)) bottom
  553.         pen (right - (width%5)) bottom
  554.         pen right top
  555.         pen (right - (width%3)) (top+(height%2))
  556.         pen (left + (width%2)) (top+(height%4))
  557.         pen (left + (width%3)) (top+(height%2))
  558.         pen left top
  559.         
  560.         /* fill it */
  561.         flood (left + (width%2)) (bottom-1)
  562.         
  563.         end
  564.     return 1
  565.  
  566.  
  567.  
  568. SetStatus: procedure
  569.     parse arg newstatus
  570.     
  571.     if (newstatus == "_LAST") then do
  572.         SetWindowTitle '"' || getclip("PrevString") || '"'
  573.         end
  574.     else do
  575.         call setclip("PrevString",newstatus)
  576.         SetWindowTitle '"' || newstatus || '"'
  577.     end
  578.     return 1
  579.     
  580.  
  581.     
  582.     
  583.     
  584.  
  585. /* Returns the point midway between two coords */
  586. MidWayBetween: procedure expose GlobData.
  587.     parse arg left, right, XorY
  588.  
  589.     if (XorY = X) then 
  590.         return trunc((GlobData.XSpace.left + GlobData.XSpace.right)/2)
  591.     else    
  592.         return trunc((GlobData.YSpace.left + GlobData.YSpace.right)/2)
  593.  
  594. ChopRange: procedure
  595.     parse arg myval, lo, hi
  596.     if (myval < lo) then return lo
  597.     if (myval > hi) then return hi
  598.     return myval
  599.     
  600.     
  601. /* --------------------------------------------------------------- */
  602. /* procedure CheckForWin                                           */
  603. /* --------------------------------------------------------------- */
  604. CheckForWin: procedure expose GlobData.
  605.     winner = nobody
  606.     negone = -1
  607.     
  608.     if (GlobData.exited.1 == 15) then winner = "Player 1"
  609.     else if (GlobData.exited.negone == 15) then winner = "Player 2"
  610.     
  611.     /* nobody one yet */
  612.     if (winner == nobody) then return 1
  613.     
  614.     EasyRequest "Winner!" '"'||winner||" has won the game!"||'"' "Okay"
  615.     call SetStatus("Game Over.  Rerun the script to play again.")
  616.     lock off
  617.     exit
  618.     return 0
  619.     
  620.         
  621. /* Transmit our move to our opponent */
  622. TransmitMove: procedure 
  623.     parse arg fx, fy, tx, ty
  624.     
  625.     sstring = '"' || fx || " " || fy || " " || tx || " " || ty || '"'
  626.     sendmessage sstring
  627.     return 1
  628.     
  629.  
  630.  
  631. TellExtraJump: procedure
  632.     parse arg jumpnum
  633.     
  634.     if (jumpnum == 1) then x = "double"
  635.     if (jumpnum == 2) then x = "triple"
  636.     if (jumpnum == 3) then x = "quadruple"
  637.     if (jumpnum == 4) then x = "quintuple"
  638.     if (jumpnum == 5) then x = "sextuple"
  639.     if (jumpnum == 6) then x = "septuple"
  640.     if (jumpnum == 7) then x = "octuple"
  641.     if (jumpnum >= 8) then x = "maliciously"
  642.     
  643.     call SetStatus("You may " || x || " jump if you wish.")
  644.     return 1
  645.     
  646.  
  647. /* procedure SetColors */
  648. SetColors: procedure
  649.     SetPenColor 0 10 10 10
  650.     SetPenColor 1 00 00 00
  651.     SetPenColor 2 15 15 15
  652.     SetPenColor 3 06 08 11
  653.     SetPenColor 4 09 09 09    /* This not used in 4-color screens; will be ignored then */
  654.     return 1
  655.